#pragma once

#include <string>
#include <vector>
#include <chrono>
#include <memory>
#include <filesystem>
#include "namespace_manager.h"
#include "cgroup_manager.h"
#include "seccomp_filter.h"
#include <nlohmann/json.hpp> // Added for nlohmann/json.hpp

namespace judge {

struct ResourceLimits {
    std::chrono::milliseconds cpu_time{std::chrono::milliseconds(1000)};  // 默认1秒
    std::size_t memory_bytes{256 * 1024 * 1024};  // 默认256MB
    std::size_t stack_bytes{8 * 1024 * 1024};  // 默认8MB
    std::size_t output_bytes{10 * 1024 * 1024};  // 默认10MB
};

enum class ExecutionStatus {
    Success = 1,
    TimeLimitExceeded = 2,
    MemoryLimitExceeded = 3,
    OutputLimitExceeded = 4,
    RuntimeError = 5,
    SystemError = 6
};

struct ExecutionResult {
    ExecutionStatus status{ExecutionStatus::SystemError};
    std::chrono::milliseconds cpu_usage{0};
    std::size_t memory_usage{0};
    std::string stdout_output;
    std::string stderr_output;
    std::string error_message;
};

enum class Verdict {
    Accepted,
    WrongAnswer,
    TimeLimitExceeded,
    MemoryLimitExceeded,
    RuntimeError,
    RestrictedSystemCall,
    CompilationError,
    SystemError
};

struct LanguageConfig {
    std::string compile_cmd;
    std::string run_cmd;
    std::vector<std::string> allowed_syscalls;
};

struct TestCaseResult {
    int case_id{0};
    std::chrono::milliseconds time_used{0};
    std::size_t memory_used{0};
    Verdict verdict{Verdict::SystemError};
    std::string output;
};

struct JudgeResult {
    std::string submission_id;
    Verdict verdict{Verdict::SystemError};
    std::chrono::milliseconds total_time{0};
    std::size_t max_memory{0};
    std::string message; // 新增: 错误/附加信息
    std::vector<TestCaseResult> results;
};

class Sandbox {
public:
    Sandbox();
    ~Sandbox();

    void setResourceLimits(const ResourceLimits& limits);
    void setCommand(const std::string& cmd, const std::vector<std::string>& args = {});
    void setWorkingDirectory(const std::string& path);
    void mountReadOnlyDirectory(const std::string& source, const std::string& target);
    void setLanguage(const std::string& lang);

    ExecutionResult execute();

    // High-level judge interface
    JudgeResult judge(const nlohmann::json& config);

private:
    // Helper methods used internally
    ExecutionResult compile(const std::string& source_code);
    TestCaseResult runTestCase(int case_id, const std::string& input, const std::string& expected_output);
    bool compareOutput(const std::string& actual, const std::string& expected);
    void setupTmpfs();
    LanguageConfig getLanguageConfig(const std::string& language);

    std::string command_;
    std::vector<std::string> arguments_;
    std::string working_dir_;
    ResourceLimits limits_;

    std::unique_ptr<NamespaceManager> namespace_manager_;
    std::unique_ptr<CgroupManager> cgroup_manager_;
    std::unique_ptr<SeccompFilter> seccomp_filter_;

    std::string language_;
    LanguageConfig language_config_;

    // Feature toggle: namespace isolation (chroot). Disabled by default for unit tests.
    bool enable_namespace_{false};
};

std::string base64Encode(const std::string& data);
std::string base64Decode(const std::string& encoded_string);

// 新增声明: 将评测结果和判决转换相关函数
std::string verdictToString(Verdict verdict);
nlohmann::json resultToJson(const JudgeResult& result);

} // namespace judge 